/*
 * Copyright (c) 2022, IMMORTA Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * - Neither the name of IMMORTA Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*!
 * @file icm_drv.c
 * @brief This file defines icm driver functions
 */

/*******Includes***************************************************************/
#include "icm_drv.h"
#include "icm_reg_access.h"
#include "clock_drv.h"


/*******Definitions************************************************************/

/*******Variables**************************************************************/
/*! @brief Table to save register base addresses for icm instances */
static ICM_Type* s_icmRegBase[CONFIG_ICM_INSTANCE_COUNT] = CONFIG_ICM_REG_BASE_PTRS;

/*! @brief Table to save icm module names */
static module_names_t s_icmModuleName[CONFIG_ICM_INSTANCE_COUNT] = CONFIG_ICM_MODULE_NAMES;

/*******Prototypes*************************************************************/

/*******Private Functions******************************************************/

/*******Code*******************************************************************/

/*******************************************************************************
 *** Function Name : ICM_SetTriggerSourceForADCNormalChannel
 *** Description   : Configure the ADC normal channel trigger source
 ******************************************************************************/
void ICM_SetTriggerSourceForADCNormalChannel(uint32_t instance,
                                             icm_adc_normal_channel_trigger_target_t triggerTarget,
                                             icm_adc_trigger_source_t triggerSource)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetTriggerSourceForADCNormalChannel(regBase, triggerTarget, triggerSource);
}

/*******************************************************************************
 *** Function Name : ICM_SetTriggerSourceForADCPriorityChannel
 *** Description   : Configure the ADC priority channel trigger source
 ******************************************************************************/
void ICM_SetTriggerSourceForADCPriorityChannel(uint32_t instance,
                                               icm_adc_priority_channel_trigger_target_t triggerTarget,
                                               icm_adc_trigger_source_t triggerSource)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetTriggerSourceForADCPriorityChannel(regBase, triggerTarget, triggerSource);
}

/*******************************************************************************
 *** Function Name : ICM_SetSPWMFaultSource
 *** Description   : Select SPWM fault source
 ******************************************************************************/
void ICM_SetSPWMFaultSource(uint32_t instance,
                            icm_spwm_fault_target_t faultTarget,
                            icm_spwm_fault_source_t faultSource)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetSPWMFaultSource(regBase, faultTarget, faultSource);
}

/*******************************************************************************
 *** Function Name : ICM_SetSPWMHardwareSyncSourceEn
 *** Description   : Configure the SPWM register hardware sync source
 ******************************************************************************/
void ICM_SetSPWMHardwareSyncSourceEn(uint32_t instance, icm_spwm_sync_target_t syncTarget, bool enable)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetSPWMHardwareSyncSourceEn(regBase, syncTarget, enable);
}

/*******************************************************************************
 *** Function Name : ICM_SetSPWM0Modulation
 *** Description   : Enable/Disable SPWM0 channel0~7 modulation with IPWM0_CH0
 ******************************************************************************/
void ICM_SetSPWM0Modulation(uint32_t instance, uint8_t channelMsk)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetSPWM0ModulationEn(regBase, channelMsk);
}

/*******************************************************************************
 *** Function Name : ICM_SetSPWM1Modulation
 *** Description   : Enable/Disable SPWM1 channel0~7 modulation with IPWM1_CH0
 ******************************************************************************/
void ICM_SetSPWM1Modulation(uint32_t instance, uint8_t channelMsk)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetSPWM1ModulationEn(regBase, channelMsk);
}

/*******************************************************************************
 *** Function Name : ICM_SetSPWMCapturePOSEn
 *** Description   : Configure the CMP paraller output to SPWM
 ******************************************************************************/
void ICM_SetSPWMCapturePOSEn(uint32_t instance,
                             icm_spwm_capture_pos_target_t target,
                             bool enable)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetSPWMCapturePOSEn(regBase, target, enable);
}

/*******************************************************************************
 *** Function Name : ICM_SetIPWMCaptureSource
 *** Description   : Configure the IPWM capture source from CMP
 ******************************************************************************/
void ICM_SetIPWMCaptureSource(uint32_t instance,
                              icm_cmp_output_trigger_target_t target,
                              icm_cmp_output_source_t source)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetIPWMCaptureSource(regBase, target, source);
}

/*******************************************************************************
 *** Function Name : ICM_SetLSICaptureEn
 *** Description   : Enable/Disable LSI capture to IPWM0_CH2
 ******************************************************************************/
void ICM_SetLSICaptureEn(uint32_t instance, bool enable)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetLSICaptureEn(regBase, enable);
}

/*******************************************************************************
 *** Function Name : ICM_SetRTCClockCaptureEn
 *** Description   : Enable/Disable RTC clock capture to IPWM0_CH3
 ******************************************************************************/
void ICM_SetRTCClockCaptureEn(uint32_t instance, bool enable)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetRTCClockCaptureEn(regBase, enable);
}

/*******************************************************************************
 *** Function Name : ICM_SetCMPWindow
 *** Description   : Configure the CMP window source
 ******************************************************************************/
void ICM_SetCMPWindow(uint32_t instance, icm_cmp_window_source_t source)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    ICM_Type* regBase = s_icmRegBase[instance];

    ICM_REG_SetCMPWindowSource(regBase, source);
}

/*******************************************************************************
 *** Function Name : ICM_Init
 *** Description   : Init ICM module about module enable & module reset
 ******************************************************************************/
void ICM_Init(uint32_t instance)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    /* Disable spwm module clock */
    CLOCK_SetModuleBusClockEnable(s_icmModuleName[instance], true);
    /* Set soft reset active of spwm module */
    CLOCK_SetModuleSoftResetState(s_icmModuleName[instance], RESET_INACTIVE);

}

/*******************************************************************************
 *** Function Name : ICM_Deinit
 *** Description   : Deinit ICM module
 ******************************************************************************/
void ICM_Deinit(uint32_t instance)
{
    ASSERT_PARAM(instance < CONFIG_ICM_INSTANCE_COUNT);

    /* Set soft reset active of spwm module */
    CLOCK_SetModuleSoftResetState(s_icmModuleName[instance], RESET_ACTIVE);
    /* Disable spwm module clock */
    CLOCK_SetModuleBusClockEnable(s_icmModuleName[instance], false);
}

/*******EOF********************************************************************/
